package com.furtherstar.auth.service.impl;

import java.util.Collections;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.furtherstar.auth.controller.dto.AppQuery;
import com.furtherstar.auth.dao.enums.Disabled;
import com.furtherstar.auth.dao.mapper.AppMapper;
import com.furtherstar.auth.dao.mapper.AppResourceMapper;
import com.furtherstar.auth.dao.model.App;
import com.furtherstar.auth.dao.model.AppExample;
import com.furtherstar.auth.dao.model.AppExample.Criteria;
import com.furtherstar.auth.dao.model.AppResourceExample;
import com.furtherstar.auth.service.AppService;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageSerializable;
import com.yummy.convention.exception.AssertUtil;
import com.yummy.convention.lang.IDGenerator;
import com.yummy.security.User;
import com.yummy.web.context.RequestContext;

@Service
public class AppServiceImpl implements AppService{
	
	@Autowired
	private AppMapper appMapper;
	@Autowired
	private AppResourceMapper appResourceMapper;

	@Override
	public Long add(App app) {
		AssertUtil.isTrue(!exist(app),"已存在");
		app.setDisabled(Disabled.normal.ordinal());
		createMark(app);
		appMapper.insert(app);
		return app.getId();
	}

	private void createMark(App app) {
		app.setId(IDGenerator.getId());
		User user = RequestContext.getCurrentUser();
		app.setLmNickname(user.getNickname());
		app.setLmTime(new Date());
		app.setLmUserid((Long)user.getUserid());
	}

	private boolean exist(App app) {
		AppExample example = new AppExample();
		example.createCriteria().andAppnameEqualTo(app.getAppname());
		return appMapper.countByExample(example) != 0;
	}

	@Override
	public Long update(App app) {
		app.setAppname(null);
		optMark(app);
		int row = appMapper.updateByPrimaryKeySelective(app);
		AssertUtil.isTrue(row == 1,"找不到记录");
		return app.getId();
	}

	private void optMark(App app) {
		User user = RequestContext.getCurrentUser();
		app.setLmNickname(user.getNickname());
		app.setLmTime(new Date());
		app.setLmUserid((Long)user.getUserid());
	}

	@Override
	public Long disable(Long appId) {
		App app = new App();
		app.setId(appId);
		app.setDisabled(Disabled.disabled.ordinal());
		optMark(app);
		int row = appMapper.updateByPrimaryKeySelective(app);
		AssertUtil.isTrue(row == 1,"找不到记录");
		return appId;
	}

	@Override
	public Long enable(Long appId) {
		App app = new App();
		app.setId(appId);
		app.setDisabled(Disabled.normal.ordinal());
		optMark(app);
		int row = appMapper.updateByPrimaryKeySelective(app);
		AssertUtil.isTrue(row == 1,"找不到记录");
		return appId;
	}

	@Override
	public Boolean delete(Long appId) {
		App app = appMapper.selectByPrimaryKey(appId);
		AssertUtil.notNull(app,"找不到记录");
		AssertUtil.isTrue(canDelete(app),"应用包含资源无法删除");
		optMark(app);
		appMapper.deleteByPrimaryKey(appId);
		return true;
	}

	private boolean canDelete(App app) {
		AppResourceExample example = new AppResourceExample();
		example.createCriteria().andAppnameEqualTo(app.getAppname());
		return appResourceMapper.countByExample(example) == 0;
	}

	@Override
	public PageSerializable<App> queryPage(AppQuery appQuery) {
		PageHelper.startPage(appQuery.getPageNum(), appQuery.getPageSize());
		List<App> list = queryList(appQuery);
		return new PageSerializable<>(list);
	}

	@Override
	public List<App> queryList(AppQuery appQuery) {
		AppExample example = new AppExample();
		Criteria criteria = example.createCriteria();
		if(StringUtils.isNotBlank(appQuery.getAppname())) {
			criteria.andAppnameLike("%"+appQuery.getAppname()+"%");
		}
		if(StringUtils.isNotBlank(appQuery.getAppTitle())) {
			criteria.andAppTitleLike("%"+appQuery.getAppTitle()+"%");
		}
		return appMapper.selectByExample(example);
	}
	@Override
	public Map<String, App> getAppMap(List<String> appnames) {
		AppExample example = new AppExample();
		example.createCriteria().andAppnameIn(appnames);
		List<App> apps = appMapper.selectByExample(example);
		if(CollectionUtils.isEmpty(apps)) {
			return Collections.emptyMap();
		}
		return apps.stream().collect(Collectors.toMap(a -> a.getAppname(), a -> a));
	}

}